/*
 * Copyright (C) 2009 Jakub Miara
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.araim.rringtone;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;

/**
 * @author Jakub Miara
 * @version 1.0
 * 
 *          This Class represents Ringtone information as it is stored in the
 *          android SQLite DB. the actual URI to a specific ringtone consists of
 *          uri stored in this class and id ( uri/id )
 * 
 */
public class RingtoneInfo implements android.os.Parcelable, Comparable<RingtoneInfo> {

	private int id;
	private String name;
	/**
	 * this is not the full URI of a ringtone, just a representation of a DB URI
	 * field
	 */
	private String uri;
	private int rtype;

	public int getRtype() {
		return rtype;
	}

	public void setRtype(int rtype) {
		this.rtype = rtype;
	}

	public RingtoneInfo() {
		super();
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getUri() {
		return uri;
	}

	public void setUri(String uri) {
		this.uri = uri;
	}

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(id);
		dest.writeString(name);
		dest.writeString(uri);
		dest.writeInt(rtype);
	}

	private RingtoneInfo(Parcel p) {
		this.id = p.readInt();
		this.name = p.readString();
		this.uri = p.readString();
		this.rtype = p.readInt();
	}

	public String getFullUri() {
		return getUri() + "/" + getId();
	}

	/**
	 * Parcelable deserializer helper - creates the object or object array from
	 * parcel
	 */
	public static final Parcelable.Creator<RingtoneInfo> CREATOR = new Parcelable.Creator<RingtoneInfo>() {

		public RingtoneInfo createFromParcel(Parcel source) {
			return new RingtoneInfo(source);
		}

		public RingtoneInfo[] newArray(int size) {
			return new RingtoneInfo[size];
		}

	};

	/**
	 * helper function to store object contents as Content-Value pair useful
	 * when writing objects to DB
	 * 
	 * @return object representation in Content-Value form
	 */
	public ContentValues getContentValues() {
		ContentValues cv = new ContentValues();
		cv.put("id", getId());
		cv.put("name", getName());
		cv.put("uri", getUri());
		cv.put("rtype", getRtype());
		return cv;
	}

	private static void setRingtoneEnabled(ContentResolver cr, Uri uri, int id, boolean enabled) {
		ContentValues cv = new ContentValues();
		cv.put(MediaStore.Audio.Media.IS_RINGTONE, enabled);
		cr.update(uri, cv, "_id = " + id, new String[0]);
	}

	private static void setNotificationEnabled(ContentResolver cr, Uri uri, int id, boolean enabled) {
		ContentValues cv = new ContentValues();
		cv.put(MediaStore.Audio.Media.IS_NOTIFICATION, enabled);
		cr.update(uri, cv, "_id = " + id, new String[0]);
	}

	private static void enableNotification(ContentResolver cr, Uri uri, int id) {
		setNotificationEnabled(cr, uri, id, true);
	}

	private static void disableNotification(ContentResolver cr, Uri uri, int id) {
		setNotificationEnabled(cr, uri, id, false);
	}

	private static void enableRingtone(ContentResolver cr, Uri uri, int id) {
		setRingtoneEnabled(cr, uri, id, true);
	}

	private static void disableRingtone(ContentResolver cr, Uri uri, int id) {
		setRingtoneEnabled(cr, uri, id, false);
	}

	public static void enable(ContentResolver cr, Uri uri, int id, int type) {
		switch (type) {
		case RingtoneManager.TYPE_RINGTONE:
			enableRingtone(cr, uri, id);
			return;
		case RingtoneManager.TYPE_NOTIFICATION:
			enableNotification(cr, uri, id);
			return;
		}
	}

	public static void disable(ContentResolver cr, Uri uri, int id, int type) {
		switch (type) {
		case RingtoneManager.TYPE_RINGTONE:
			disableRingtone(cr, uri, id);
			return;
		case RingtoneManager.TYPE_NOTIFICATION:
			disableNotification(cr, uri, id);
			return;
		}
	}

	public static Uri insertRingtone(ContentResolver cv, String path, String title, String artist, String album, int year,
			boolean ringtone, boolean notification) {

		ContentValues values = new ContentValues();

		values.put(MediaStore.MediaColumns.TITLE, title);
		if (artist != null) {
			values.put(MediaStore.Audio.Media.ARTIST, artist);
		}
		if (album != null) {
			values.put(MediaStore.Audio.Media.ALBUM, album);
		}
		values.put(MediaStore.Audio.Media.YEAR, year);
		values.put(MediaStore.MediaColumns.DATA, path);

		values.put(MediaStore.Audio.Media.IS_RINGTONE, ringtone);
		values.put(MediaStore.Audio.Media.IS_NOTIFICATION, notification);
		values.put(MediaStore.Audio.Media.IS_ALARM, false);
		values.put(MediaStore.Audio.Media.IS_MUSIC, true);

		// Insert it into the database
		Uri uri = MediaStore.Audio.Media.getContentUriForPath(path);

		return cv.insert(uri, values);
	}

	public int compareTo(RingtoneInfo another) {
		if (this.equals(another)) {
			return 0;
		}
		if (this.name == null) {
			return -1;
		}
		return this.name.compareToIgnoreCase(another.name);
	}

	@Override
	public boolean equals(Object o) {
		if (o == this) {
			return true;
		}
		if (o == null) {
			return false;
		}

		if (o instanceof RingtoneInfo) {
			if (this.name == null) {
				if (((RingtoneInfo) o).name != null) {
					return false;
				}
			}
			if (this.uri == null) {
				if (((RingtoneInfo) o).uri != null) {
					return false;
				}
			}
			if (((RingtoneInfo) o).id == this.id) {
				if ((this.uri == null || this.uri.equals(((RingtoneInfo) o).uri))
						&& (this.name == null || this.name.equals(((RingtoneInfo) o).name)) && this.rtype == ((RingtoneInfo) o).rtype) {
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	public static boolean isValidNotification(Context ctx, RingtoneInfo ri) {
		Cursor c = ctx.getContentResolver().query(Uri.parse(ri.getUri()), new String[] { "_id" },
				MediaStore.Audio.Media._ID + " = ? AND " + MediaStore.Audio.Media.IS_NOTIFICATION + " = 1",
				new String[] { String.valueOf(ri.getId())}, null);
		boolean retval = false;
		if (c.moveToFirst()) {
			retval = true;
		}
		c.close();
		return retval;
	}
}